package com.spring.component.utils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author liushihua
 * @since 2018年03月20日
 */
public class HttpClientUtil {
  private static final CloseableHttpClient httpClient;
  private static final String CHARSET = "UTF-8";
  private static final Logger log = LoggerFactory.getLogger(HttpClientUtil.class);

  static {
    RequestConfig config =
        RequestConfig.custom().setConnectTimeout(60000).setSocketTimeout(15000).build();
    httpClient = HttpClientBuilder.create().setDefaultRequestConfig(config).build();
  }

  public static String doGet(String url) {
    if (CollectionUtil.isBlank(url)) {
      return null;
    }
    HttpGet httpGet = new HttpGet(url);
    return todo(httpGet, null, CHARSET);
  }

  /**
   * http get的请求
   * 
   * @param url 请求url，包括http协议标识
   * @param params 提交参数
   * @param charset 字符编码
   * @param headers 请求头
   * @return
   */
  public static String doGet(String url, Map<String, String> params, String charset,
      Map<String, String> headers) {
    if (CollectionUtil.isBlank(url)) {
      return null;
    } else {
    }
    try {
      if (CollectionUtil.isNotBlank(params)) {
        List<NameValuePair> nameValuePairs = new ArrayList<>();
        params.forEach((k, v) -> nameValuePairs.add(new BasicNameValuePair(k, v)));
        // 拼接带参数的get请求url
        url = url + "?" + EntityUtils.toString(new UrlEncodedFormEntity(nameValuePairs, charset));
      }

      HttpGet httpGet = new HttpGet(url);
      if (CollectionUtil.isNotBlank(headers)) {
        headers.forEach((k, v) -> httpGet.setHeader(k, v));
      }
      return todo(httpGet, params, charset);
    } catch (IOException e) {
      log.error("调用httpClient错误，url：{}--------{}", url, e.getMessage());
      return null;
    }
  }

  public static String doPost(String url, Map<String, String> bodys) {
    if (CollectionUtil.isBlank(url)) {
      return null;
    }
    HttpPost httpPost = new HttpPost(url);
    return todo(httpPost, bodys, CHARSET);
  }

  /**
   * http post的请求
   *
   * @param url 请求url，包括http协议标识
   * @param bodys 提交参数
   * @param charset 字符编码
   * @param headers 请求头
   * @return
   */
  public static String doPost(String url, Map<String, String> bodys, String charset,
      Map<String, String> headers) {
    if (CollectionUtil.isBlank(url)) {
      return null;
    }
    HttpPost httpPost = new HttpPost(url);
    if (CollectionUtil.isNotBlank(headers)) {
      headers.forEach((k, v) -> httpPost.setHeader(k, v));
    }
    return todo(httpPost, bodys, charset);
  }

  private static String todo(HttpRequestBase http, Map<String, String> params, String charset) {
    try {
      if (CollectionUtil.isNotBlank(params)) {
        List<NameValuePair> nameValuePairs = new ArrayList<>();
        params.forEach((k, v) -> nameValuePairs.add(new BasicNameValuePair(k, v)));
        ((HttpEntityEnclosingRequestBase) http)
            .setEntity(new UrlEncodedFormEntity(nameValuePairs, charset));
      }
      CloseableHttpResponse response = httpClient.execute(http);
      int statusCode = response.getStatusLine().getStatusCode();
      if (statusCode != 200) {
        http.abort();
        throw new RuntimeException("HttpClient,error status code :" + statusCode);
      } else {
        HttpEntity entity = response.getEntity();
        String result = entity == null ? null : EntityUtils.toString(entity, CHARSET);
        EntityUtils.consume(entity);
        response.close();
        return result;
      }
    } catch (IOException e) {
      log.error("调用httpClient错误，url：{}--------{}", http.getURI(), e);
      return null;
    }
  }
}
